home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / falcon / programm.ing / asm56.zoo / a56.y < prev    next >
Text File  |  1992-11-14  |  39KB  |  1,754 lines

  1. %{
  2. /*******************************************************
  3.  *
  4.  *  a56 - a DSP56001 assembler
  5.  *
  6.  *  Written by Quinn C. Jensen
  7.  *  July 1990
  8.  *  jensenq@npd.novell.com (or jensenq@qcj.icon.com)
  9.  *
  10.  *******************************************************\
  11.  
  12. /*
  13.  * Copyright (C) 1990-1992 Quinn C. Jensen
  14.  *
  15.  * Permission to use, copy, modify, distribute, and sell this software
  16.  * and its documentation for any purpose is hereby granted without fee,
  17.  * provided that the above copyright notice appear in all copies and
  18.  * that both that copyright notice and this permission notice appear
  19.  * in supporting documentation.  The author makes no representations
  20.  * about the suitability of this software for any purpose.  It is
  21.  * provided "as is" without express or implied warranty.
  22.  *
  23.  */
  24.  
  25. /*
  26.  *  a56.y - The YACC grammar for the assembler.
  27.  *
  28.  *  Note:  This module requires a "BIG" version of YACC.  I had to
  29.  *  recompile YACC in the largest mode available.
  30.  *
  31.  *  Other notes:
  32.  *
  33.  *  MOVEC, MOVEM and MOVEP must be used explicitly--MOVE can't yet figure
  34.  *  out which form to use.
  35.  *
  36.  */
  37.  
  38. #include "a56.h"
  39. unsigned int w0, w1, pc;
  40. extern BOOL list_on;
  41. BOOL uses_w1;
  42. int just_rep = 0;
  43. extern char inline[];
  44. char *spaces(), *luntab();
  45. char segs[] = "PXYL";
  46. int seg;
  47. int substatement = 0;
  48. BOOL long_symbolic_expr = FALSE;
  49.  
  50. struct n binary_op();
  51. struct n unary_op();
  52. struct n sym_ref();
  53.  
  54. #define R_R6            0x0001
  55. #define R_R5            0x0002
  56. #define R_R4            0x0004
  57. #define R_DATA_ALU_ACCUM    0x0008
  58. #define R_CTL_REG        0x0010
  59. #define R_FUNKY_CTL_REG        0x0020
  60. #define R_SDX            0x0040
  61. #define R_SDY            0x0080
  62. #define R_LSD            0x0100
  63. #define R_AB            0x0200
  64. #define R_XREG            0x0400
  65. #define R_YREG            0x0800
  66. /* registers to which short immediate move is an unsigned int */
  67. #define R_UINT            0x1000
  68. /* registers to which short immediate move is an signed frac */
  69. #define R_SFRAC            0x2000
  70. %}
  71.  
  72. %union {
  73.     int ival;    /* integer value */
  74.     struct n n;    /* just like in struct sym */
  75.     double dval;    /* floating point value */
  76.     char *sval;    /* string */
  77.     int cval;    /* character */
  78.     char cond;    /* condition */
  79.     struct regs {
  80.         int r6, r5, r4, data_alu_accum, ctl_reg, funky_ctl_reg;
  81.         int sdx, sdy, lsd, ab, xreg, yreg;
  82.         int flags;
  83.     } regs;
  84.     struct ea {
  85.         int mode;
  86.         int ext;
  87.         int pp;
  88.     } ea;
  89. }
  90.  
  91. %token <n> CHEX CDEC FRAC 
  92. %token <ival> AREG BREG MREG NREG RREG XREG YREG
  93. %token <ival> OP OPA OPP
  94. %token <cond> OP_JCC OP_JSCC OP_TCC
  95. %token <sval> SYM
  96. %token <sval> STRING
  97. %token <cval> CHAR
  98. %token COMMENT
  99. %token XMEM
  100. %token YMEM
  101. %token LMEM
  102. %token PMEM
  103. %token AAAA
  104. %token A10
  105. %token BBBB
  106. %token B10
  107. %token AABB
  108. %token BBAA
  109. %token XXXX
  110. %token YYYY
  111. %token SR
  112. %token MR
  113. %token CCR
  114. %token OMR
  115. %token SP
  116. %token SSH
  117. %token SSL
  118. %token LA
  119. %token LC
  120. %token EOL
  121. %token EOS
  122.  
  123. %token OP_ABS
  124. %token OP_ADC
  125. %token OP_ADD
  126. %token OP_ADDL
  127. %token OP_ADDR
  128. %token OP_ASL
  129. %token OP_ASR
  130. %token OP_CLR
  131. %token OP_CMP
  132. %token OP_CMPM
  133. %token OP_DIV
  134. %token OP_MAC
  135. %token OP_MACR
  136. %token OP_MPY
  137. %token OP_MPYR
  138. %token OP_NEG
  139. %token OP_NORM
  140. %token OP_RND
  141. %token OP_SBC
  142. %token OP_SUB
  143. %token OP_SUBL
  144. %token OP_SUBR
  145. %token OP_TFR
  146. %token OP_TST
  147. %token OP_AND
  148. %token OP_ANDI
  149. %token OP_EOR
  150. %token OP_LSL
  151. %token OP_LSR
  152. %token OP_NOT
  153. %token OP_OR
  154. %token OP_ORI
  155. %token OP_ROL
  156. %token OP_ROR
  157. %token OP_BCLR
  158. %token OP_BSET
  159. %token OP_BCHG
  160. %token OP_BTST
  161. %token OP_DO
  162. %token OP_ENDDO
  163. %token OP_LUA
  164. %token OP_MOVE
  165. %token OP_MOVEC
  166. %token OP_MOVEM
  167. %token OP_MOVEP
  168. %token OP_ILLEGAL
  169. %token OP_INCLUDE
  170. %token OP_JMP
  171. %token OP_JCLR
  172. %token OP_JSET
  173. %token OP_JSR
  174. %token OP_JSCLR
  175. %token OP_JSSET
  176. %token OP_NOP
  177. %token OP_REP
  178. %token OP_RESET
  179. %token OP_RTI
  180. %token OP_RTS
  181. %token OP_STOP
  182. %token OP_SWI
  183. %token OP_WAIT
  184. %token OP_EQU
  185. %token OP_ORG
  186. %token OP_DC
  187. %token OP_END
  188. %token OP_PAGE
  189. %token OP_PSECT
  190. %token OP_ALIGN
  191. %token SHL
  192. %token SHR
  193.  
  194. %type <n> num num_or_sym 
  195. %type <n> num_or_sym_expr
  196. %type <n> expr
  197. %type <n> ix
  198. %type <n> ix_long
  199.  
  200. %type <ival> abs_addr abs_short_addr io_short_addr 
  201. %type <ival> a_b x_or_y ea b5_10111_max
  202. %type <ival> p6_ean_a6 ea_no_ext p6_ea_a6 ea_a6 ea_a12
  203. %type <ival> ea_no_ext 
  204. %type <ival> ea_short
  205. %type <ival> prog_ctl_reg
  206. %type <ival> op8_1 op8_2 op8_3 op8_4 op8_5 op8_6 op8_7 op8_8
  207. %type <ival> mpy_arg mpy_srcs plus_minus
  208. %type <ival> sd3
  209. %type <ival> funky_ctl_reg tcc_sd space
  210.  
  211. %type <regs> regs
  212. %type <ea> movep_ea_pp
  213.  
  214. %left '|'
  215. %left '^'
  216. %left SHL SHR
  217. %left '&'
  218. %left '+' '-'
  219. %left '*' '/' '%'
  220. %right '~'
  221.  
  222. %start input
  223.  
  224. %%
  225.  
  226. /*%%%********************* top syntax ***********************/
  227.  
  228. input    :    /* empty */
  229.     |    input statement
  230.     ;
  231.  
  232. statement
  233.     :    good_stuff EOL
  234.             {substatement = 0;
  235.             if(NOT check_psect(seg, pc) && pass == 2)
  236.                 yyerror("%04X: psect violation", pc);
  237.             }
  238.     |    good_stuff EOS
  239.             {substatement++;
  240.             if(NOT check_psect(seg, pc) && pass == 2)
  241.                 yyerror("%04X: psect violation", pc);
  242.             }
  243.     |    error
  244.     ;
  245.  
  246. good_stuff
  247.     :    /* empty */
  248.             {if(pass == 2 && list_on) {
  249.                 printf("\n");
  250.             }}
  251.     |    cpp_droppings
  252.     |    COMMENT
  253.             {if(pass == 2 && NOT substatement && list_on) {
  254.                 printf("%s%s\n", spaces(0), luntab(inline));
  255.             }}
  256.     |    assembler_ops comment_field
  257.             {long_symbolic_expr = FALSE;}
  258.     |    label_field operation_field comment_field
  259.             {char *printcode();
  260.             if(pass == 2) {
  261.                 gencode(seg, pc, w0);
  262.                 if(list_on) printf("%c:%04X %s %s\n", segs[seg], pc, 
  263.                     printcode(w0), substatement ? "" :
  264.                         luntab(inline));
  265.                 pc++;
  266.                 if(uses_w1) {
  267.                     gencode(seg, pc, w1);
  268.                     if(list_on) printf("%c:%04X %s\n", segs[seg], pc,
  269.                                printcode(w1 & 0xFFFFFF));
  270.                     pc++;
  271.                 }
  272.             } else {
  273.                 pc++;
  274.                 if(uses_w1)
  275.                     pc++;
  276.             }
  277.             w0 = w1 = 0; uses_w1 = FALSE; 
  278.             long_symbolic_expr = FALSE;}
  279.     |    SYM comment_field
  280.             {sym_def($1, INT, pc);
  281.             free($1);
  282.             if(pass == 2) {
  283.                 if(list_on) printf("%c:%04X%s%s\n", segs[seg], pc, 
  284.                     spaces(14-8), substatement ? "" :
  285.                         luntab(inline));
  286.             long_symbolic_expr = FALSE;
  287.             }}
  288.     ;
  289.  
  290. cpp_droppings
  291.     :    '#' num STRING
  292.             {if(strlen($3) > 0)
  293.                 curfile = $3;
  294.             curline = $2.val.i - 2;}
  295.     ;
  296.  
  297. assembler_ops
  298.     :    SYM OP_EQU expr
  299.             {sym_def($1, $3.type, $3.val.i, $3.val.f);
  300.             free($1);
  301.             if(pass == 2 && list_on) {
  302.                 if($3.type == INT)
  303.                     printf("%06X%s",
  304.                         $3.val.i & 0xFFFFFF,
  305.                         spaces(14-6-2));
  306.                 else
  307.                     printf("%10g%s", $3.val.f,
  308.                         spaces(14-10-2));
  309.                 printf("%s\n", 
  310.                     substatement ? "" : luntab(inline));
  311.             }}
  312.     |    OP_ALIGN expr
  313.             {int ival = n2int($2);
  314.             if($2.type == UNDEF) {
  315.                 yyerror("illegal forward reference");
  316.             } else if (ival <= 1) {
  317.                 yyerror("%d: illegal alignment", ival);
  318.             } else {
  319.                 if(pc % ival != 0)
  320.                     pc += ival - pc % ival;
  321.             }
  322.             if(pass == 2 && list_on)
  323.                 printf("%c:%04X%s%s\n", segs[seg], pc, 
  324.                     spaces(14-8), substatement ? "" : luntab(inline));
  325.             }
  326.     |    OP_PSECT SYM
  327.             {struct psect *pp = find_psect($2);
  328.             if(NOT pp) {
  329.                 if(pass == 2)
  330.                     yyerror("%s: undefined psect", $2);
  331.             } else {
  332.                 seg = pp->seg;
  333.                 pc = pp->pc;
  334.                 set_psect(pp);
  335.                 if(pass == 2 && list_on) 
  336.                     printf("%c:%04X%s%s\n", segs[seg], pc, 
  337.                         spaces(14-8), substatement ? "" : luntab(inline));
  338.             }
  339.             free($2);}
  340.     |    OP_PSECT SYM space expr ':' expr
  341.             {new_psect($2, $3, n2int($4), n2int($6));
  342.             if(pass == 2 && list_on) 
  343.                 printf("%c:%04X %04X%s%s\n", 
  344.                     segs[$3], n2int($4), n2int($6), spaces(14-8+4+1), 
  345.                     substatement ? "" : luntab(inline));
  346.             }
  347.     |    OP_ORG space expr
  348.             {pc = n2int($3);
  349.             seg = $2;
  350.             if(pass == 2 && list_on) 
  351.                 printf("%c:%04X%s%s\n", segs[seg], pc, 
  352.                     spaces(14-8), substatement ? "" : luntab(inline));
  353.             }
  354.     |    OP_ORG space expr ',' space expr
  355.             {pc = n2int($3);
  356.             seg = $2;
  357.             if(pass == 2 && list_on)
  358.                 printf("%c:%04X%s%s\n", segs[seg], pc, 
  359.                     spaces(14-8), substatement ? "" : luntab(inline));
  360.             }
  361.     |    label_field OP_DC dc_list
  362.     |    OP_PAGE num ',' num ',' num ',' num
  363.             {if(pass == 2 && NOT substatement && list_on) {
  364.                 printf("%s%s\n", spaces(0), luntab(inline));
  365.             }}
  366.     |    OP_INCLUDE STRING
  367.             {if(pass == 2 && NOT substatement && list_on) {
  368.                 printf("%s%s\n", spaces(0), luntab(inline));
  369.             }
  370.             include($2); /* free($2); */
  371.             }
  372.     |    OP_END
  373.             {if(pass == 2 && NOT substatement && list_on) {
  374.                 printf("%s%s\n", spaces(0), luntab(inline));
  375.             }}
  376.     ;
  377.  
  378. dc_list
  379.     :    dc_list ',' dc_stuff
  380.     |    dc_stuff
  381.     ;
  382.  
  383. dc_stuff
  384.     :    STRING
  385.             {int len = strlen($1), i; char *cp; w0 = 0;
  386.